home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / KSLIB11.ARJ / DEMO1.C < prev    next >
Text File  |  1991-10-16  |  12KB  |  739 lines

  1. /*****************************************************************************
  2. *
  3. *    Library Demo
  4. *
  5. *    By Kevin Spencer, DigiServ        (c) 1991
  6. *
  7. *    Edit History
  8. *    ------------
  9. *
  10. *****************************************************************************/
  11.  
  12. /*
  13. *    Defines
  14. */
  15.  
  16. #define title    "Library Demo Program"
  17. #define version "1.1"
  18. #define verdate "14-Oct-91"
  19.  
  20. #define SHOWTIME 200
  21.  
  22. /*
  23. *    System includes
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <conio.h>
  28. #include <stdlib.h>
  29. #include <ctype.h>
  30. #include <stdarg.h>
  31. #include <string.h>
  32. #include <dos.h>
  33.  
  34. /*
  35. *    Project includes
  36. */
  37.  
  38. #include "stdinc.h"
  39. #include "misc.h"
  40. #include "wn.h"
  41. #include "mn.h"
  42. #include "kb.h"
  43. #include "arg.h"
  44. #include "cf.h"
  45. #include "pr.h"
  46. #include "sc.h"
  47. #include "db.h"
  48.  
  49. /*
  50. *    Structures
  51. */
  52.  
  53. struct rec_st {
  54.     char    sn[21];
  55.     char    fn[21];
  56.     char    addr1[31];
  57.     char    addr2[31];
  58.     char    phon[11];
  59.     char    paid;
  60. };
  61.  
  62. typedef struct rec_st rec_st;
  63.  
  64. /*
  65. *    Function prototypes
  66. */
  67.  
  68. void    main(void);
  69. void    initsystem(void);
  70. int        seekfunc(rec_st *,rec_st *);
  71. int        findfunc(rec_st *,rec_st *);
  72. void    search(void);
  73. int        checksave(void);
  74. void    save(void);
  75. int        scandata(rec_st *);
  76. int        selectrec(int);
  77. void    message(char *,...);
  78. void    help(void);
  79. void    popup(char *);
  80. int        getans(char *);
  81. void    scan(void);
  82. void    pack(void);
  83. void    add(void);
  84. void    delete(void);
  85. void    back(void);
  86. void    next(void);
  87. void    clear(void);
  88. int        reports(void);
  89. void    rbrief(void);
  90. void    prerr(char *);
  91. void    rfull(void);
  92. void    rpaid(void);
  93. void    header(char *);
  94.  
  95. /*
  96. *    Configuration parameters
  97. */
  98.  
  99. struct conf_st {
  100.     char    datafile[65];
  101.     char    indexfile[65];
  102.     char    helpfile[65];
  103.     char    tempfile[65];
  104.     char    tempidx[65];
  105.     uint    norm;
  106.     uint    high;
  107. }    conf = {
  108.     "patient.dat",
  109.     "patient.idx",
  110.     "prs.hlp",
  111.     "temp.dat",
  112.     "temp.idx",
  113.     WHITE,
  114.     BLACK|BKGR(RED),
  115. };
  116.  
  117. CFdata    config[] = {
  118.     'S',"datafile",&conf.datafile,
  119.     'S',"indexfile",&conf.indexfile,
  120.     'S',"helpfile",&conf.helpfile,
  121.     'S',"tempfile",&conf.tempfile,
  122.     'S',"tempidx",&conf.tempidx,
  123.     'C',"norm",&conf.norm,
  124.     'C',"high",&conf.high,
  125.     NULL,NULL,NULL
  126. };
  127.  
  128. /*
  129. *    Global variables
  130. */
  131.  
  132. static    rec_st    rec;
  133. static    rec_st    frec;
  134. static    int        recn[20];
  135. static    char    recs[20][81];
  136.  
  137. static    SCdata    screen[] = {
  138.     'S',20,0,17, 1,0,0,&rec.sn,NULL,
  139.     'S',20,0,17, 2,0,0,&rec.fn,NULL,
  140.     'S',30,0,17, 4,0,0,&rec.addr1,NULL,
  141.     'S',30,0,17, 5,0,0,&rec.addr2,NULL,
  142.     'S',10,0,17, 7,0,0,&rec.phon,NULL,
  143.     'L', 1,0,17, 9,0,0,&rec.paid,NULL,
  144.     '0',0,0,0,0,0,0,NULL,NULL
  145. };
  146.  
  147. MNdata    reportmenu =    {    4,40,0,0,CENTRE,
  148.                             " Report Menu ",
  149.                             "Brief Listing",NULL,rbrief,
  150.                             "Full Listing",NULL,rfull,
  151.                             "Unpaid patients",NULL,rpaid,
  152.                             NULL,NULL,NULL
  153.                         };
  154.  
  155. MNdata    cmdmenu =        {    4,40,0,0,CENTRE,
  156.                             " Command Menu ",
  157.                             "Help",NULL,help,
  158.                             "Search for patient",NULL,search,
  159.                             "Add patient",NULL,add,
  160.                             "Save patient",NULL,save,
  161.                             "Delete patient",NULL,delete,
  162.                             "List patients",NULL,scan,
  163.                             "Report menu",&reportmenu,NULL,
  164.                             "Pack database",NULL,pack,
  165.                             "Previous patient",NULL,back,
  166.                             "Next patient",NULL,next,
  167.                             "Clear screen",NULL,clear,
  168.                             NULL,NULL,NULL
  169.                         };
  170.  
  171. char    confarg[81];
  172. DBfile    *curr;            /* Pointer to current database file                    */
  173. char    pline[] = "--------------------------------------------------------------------------------";
  174. int        cf;
  175.  
  176. /*
  177. *    Start of code
  178. */
  179.  
  180. void
  181. main()
  182. {
  183.     int        exitloop;
  184.  
  185.     initsystem();
  186.  
  187.     if ((curr = DBopen(conf.datafile,sizeof(rec_st))) == NULL) {
  188.         WNdisplay(20,10,"Database inaccessible - Press any key : ");
  189.         KBgetch();
  190.         exit(1);
  191.     }
  192.  
  193.     if (DBindex(conf.indexfile,findfunc) < 0) {
  194.         WNdisplay(20,10,"Index file inaccessible - Press any key : ");
  195.         KBgetch();
  196.         exit(1);
  197.     }
  198.  
  199.     WNdisplay(2,1,"Surname      :");
  200.     WNdisplay(2,2,"First name   :");
  201.     WNdisplay(2,4,"Address 1    :");
  202.     WNdisplay(2,5,"Address 2    :");
  203.     WNdisplay(2,7,"Phone number :");
  204.     WNdisplay(2,9,"Paid :");
  205.  
  206.     DBgo(0);
  207.     SCclear(screen);
  208.     cf = 0;
  209.     exitloop = FALSE;
  210.     while (!exitloop) {
  211.         switch(SCgetscreen(screen,&cf)) {
  212.             case ESCAPE :
  213.                 checksave();
  214.                 exitloop = TRUE;
  215.                 break;
  216.             case F1 :
  217.                 help();
  218.                 break;
  219.             case F2 :
  220.                 search();
  221.                 break;
  222.             case F3 :
  223.                 add();
  224.                 break;
  225.             case F4 :
  226.                 save();
  227.                 break;
  228.             case F5 :
  229.                 delete();
  230.                 break;
  231.             case F6 :
  232.                 scan();
  233.                 break;
  234.             case F7 :
  235.                 MNmenu(&reportmenu);
  236.                 break;
  237.             case F8 :
  238.                 pack();
  239.                 break;
  240.             case F9 :
  241.                 MNmenu(&cmdmenu);
  242.                 break;
  243.             case F0 :
  244.                 clear();
  245.                 break;
  246.             case CPGUP :
  247.                 back();
  248.                 break;
  249.             case CPGDN :
  250.                 next();
  251.                 break;
  252.         }
  253.     }
  254. }
  255.  
  256. void
  257. initsystem()
  258. {
  259.     getopt("c:",NULL,confarg);
  260.     CFconf(confarg,config);
  261.     MNcolor(conf.norm,conf.high);
  262.  
  263.     WNopen(1,1,80,3,conf.norm,SINGLE,NULL);
  264.     WNgotoxy(39-(strlen(title)+strlen(version)+4)/2,1);
  265.     WNprintf("%s (v%s)",title,version);
  266.     WNopen(1,4,80,25,conf.norm,DOUBLE,NULL);
  267. }
  268.  
  269. void
  270. pack()
  271. {
  272.     int        r;
  273.     DBfile    *temp;
  274.  
  275.     if (!getans("Packing database - Are you sure (Y/N) ? "))
  276.         return;
  277.  
  278.     if ((temp = DBopen(conf.tempfile,sizeof(rec_st))) == NULL) {
  279.         message("Can't open temporary file - Press any key");
  280.         return;
  281.     }
  282.     if (DBindex(conf.tempidx,findfunc) < 0) {
  283.         message("Can't open temporary index - Press any key");
  284.         DBclose();
  285.         remove(conf.tempfile);
  286.         return;
  287.     }
  288.  
  289.     WNopen(1,1,80,3,conf.norm,DOUBLE|POPUP,NULL);
  290.     r = 1;
  291.     DBselect(curr);
  292.     DBgo(DBtop());
  293.     while (DBrecno() != 0) {
  294.         DBread(&rec);
  295.         WNprintf("\r\nCopying record %d (%s)",r,rec.sn);
  296.         DBselect(temp);
  297.         DBadd(&rec);
  298.         DBselect(curr);
  299.         DBskip(1);
  300.         r++;
  301.     }
  302.  
  303.     DBselect(temp);
  304.     DBclose();        /* Temp database */
  305.     DBclose();        /* Real database */
  306.     remove(conf.datafile);
  307.     remove(conf.indexfile);
  308.     rename(conf.tempfile,conf.datafile);
  309.     rename(conf.tempidx,conf.indexfile);
  310.     curr = DBopen(conf.datafile,sizeof(rec_st));
  311.     DBindex(conf.indexfile,findfunc);
  312.     WNclose();
  313.     DBgo(0);
  314.     SCclear(screen);
  315. }
  316.  
  317. void
  318. add()
  319. {
  320.     if ((DBfindrec(&rec) == 0) ||
  321.         (getans("Are you sure you want to add this patient (Y/N) ? "))) {
  322.         popup("Adding");
  323.         DBadd(&rec);
  324.         WNclose();
  325.     }
  326. }
  327.  
  328. void
  329. delete()
  330. {
  331.     if (DBrecno() == 0) {
  332.         message("No patient selected - Press any key");
  333.     }
  334.     else {
  335.         if (getans("Are you sure you want to delete this patient (Y/N) ? ")) {
  336.             popup("Deleting");
  337.             DBdelete(&rec);
  338.             WNclose();
  339.         }
  340.     }
  341. }
  342.  
  343. void
  344. back()
  345. {
  346.     if (DBrecno() != DBtop()) {
  347.         checksave();
  348.         DBskip(-1);
  349.         DBread(&rec);
  350.         SCshow(screen);
  351.     }
  352. }
  353.  
  354. void
  355. next()
  356. {
  357.     if (DBrecno() != DBbot()) {
  358.         checksave();
  359.         DBskip(1);
  360.         DBread(&rec);
  361.         SCshow(screen);
  362.     }
  363. }
  364.  
  365. void
  366. clear()
  367. {
  368.     checksave();
  369.     DBgo(0);
  370.     SCclear(screen);
  371.     cf = 0;
  372. }
  373.  
  374. void
  375. scan()
  376. {
  377.     int        exitloop;
  378.     rec_st    t;
  379.     int        i;
  380.     int        orn;
  381.     int        tmprn;
  382.  
  383.     WNopen(1,4,80,25,conf.norm,DOUBLE|POPUP,NULL);
  384.     tmprn = DBrecno();
  385.     orn = -1;
  386.     exitloop = FALSE;
  387.     while (!exitloop) {
  388.         if (DBrecno() == 0)
  389.             DBgo(DBtop());
  390.         if (DBrecno() != orn) {
  391.             orn = DBrecno();
  392.             WNclear();
  393.             for (i=1; (i<=20) && (DBrecno() != 0); i++) {
  394.                 DBread(&t);
  395.                 WNgotoxy(2,i);
  396.                 WNprintf("%-20s %-20s %-34.34s",t.sn,t.fn,t.addr1);
  397.                 DBskip(1);
  398.             }
  399.             DBskip(-20);
  400.         }
  401.         switch(KBgetch()) {
  402.             case ESCAPE :
  403.                 exitloop = TRUE;
  404.                 break;
  405.             case PGUP :
  406.                 DBskip(-20);
  407.                 if (DBrecno() == 0)
  408.                     DBgo(DBtop());
  409.                 break;
  410.             case PGDN :
  411.                 DBskip(40);
  412.                 DBskip(-20);
  413.                 break;
  414.         }
  415.     }
  416.     WNclose();
  417.     DBgo(tmprn);
  418. }
  419.  
  420. void
  421. save()
  422. {
  423.     if (DBrecno() == 0)
  424.         return;
  425.  
  426.     DBread(&frec);
  427.     if (findfunc(&rec,&frec)) {
  428.         if (!getans("Patient surname changed - Add new patient (Y/N) ? ")) {
  429.             popup("Saving");
  430.             DBdelete(&rec);
  431.             DBadd(&rec);
  432.             WNclose();
  433.         }
  434.         else {
  435.             popup("Adding");
  436.             DBadd(&rec);
  437.             WNclose();
  438.         }
  439.     }
  440.     else {
  441.         popup("Saving");
  442.         DBwrite(&rec);
  443.         WNclose();
  444.     }
  445. }
  446.  
  447. int
  448. seekfunc(r1,r2)
  449.     rec_st    *r1;
  450.     rec_st    *r2;
  451. {
  452.     return(r1->sn[0] == '\0' ? 0 : strnicmp(r1->sn,r2->sn,strlen(r1->sn)));
  453. }
  454.  
  455. int
  456. findfunc(r1,r2)
  457.     rec_st    *r1;
  458.     rec_st    *r2;
  459. {
  460.     return(stricmp(r1->sn,r2->sn));
  461. }
  462.  
  463. void
  464. help()
  465. {
  466.     FILE    *fp;
  467.     char    s[81];
  468.  
  469.     WNopen(1,4,80,25,conf.norm,DOUBLE|POPUP,NULL);
  470.     if ((fp = fopen(conf.helpfile,"rt")) == NULL) {
  471.         WNdisplay(20,10,"Help not available - Press any key : ");
  472.     }
  473.     else {
  474.         while (fgets(s,80,fp)) {
  475.             WNputs(s);
  476.             WNputc('\r');
  477.         }
  478.         WNdisplay(1,20,"Press any key : ");
  479.     }
  480.     KBgetch();
  481.     fclose(fp);
  482.     WNclose();
  483. }
  484.  
  485. int
  486. checksave()
  487. {
  488.     if (DBrecno() == 0)
  489.         return(TRUE);
  490.  
  491.     DBread(&frec);
  492.     if (!DBcmp(&rec,&frec))
  493.         return(TRUE);
  494.  
  495.     if (getans("Current patient has been updated - Save (Y/N) ? "))
  496.         save();
  497.  
  498.     return(TRUE);
  499. }
  500.  
  501. void
  502. search()
  503. {
  504.     int        n;
  505.     int        r;
  506.  
  507.     n = scandata(&rec);
  508.     if (n == 1) {
  509.         checksave();
  510.         DBreadn(recn[0],&rec);
  511.         SCshow(screen);
  512.     }
  513.     else if (n == 0) {
  514.         if (getans("Patient not found - Add (Y/N) ? ")) {
  515.             popup("Adding");
  516.             DBadd(&rec);
  517.             WNclose();
  518.         }
  519.     }
  520.     else {
  521.         if ((r = selectrec(n)) > 0) {
  522.             checksave();
  523.             DBreadn(r,&rec);
  524.             SCshow(screen);
  525.         }
  526.     }
  527. }
  528.  
  529. int
  530. scandata(r)
  531.     rec_st    *r;
  532. {
  533.     int        n = 0;
  534.     int        rn;
  535.     rec_st    t;
  536.     int        currn;
  537.  
  538.     currn = DBrecno();
  539.     for (rn = DBseekfirst(r,seekfunc); (n<20) && (rn>0);
  540.         rn = DBseeknext(r,seekfunc)) {
  541.         DBreadn(rn,&t);
  542.         sprintf(recs[n]," %-20s %-20s %-32.32s ",t.sn,t.fn,t.addr1);
  543.         recn[n++] = rn;
  544.     }
  545.     DBgo(currn);
  546.  
  547.     return(n);
  548. }
  549.  
  550. int
  551. selectrec(n)
  552.     int        n;
  553. {
  554.     int        i;
  555.     int        l;
  556.     int        ol;
  557.     int        exitloop;
  558.     int        retval;
  559.  
  560.     WNopen(1,4,80,25,conf.norm,DOUBLE|POPUP,NULL);
  561.     for (i=0; i<n; i++) {
  562.         WNdisplay(2,i+1,recs[i]);
  563.     }
  564.  
  565.     l = 0;
  566.     ol = -1;
  567.     retval = 0;
  568.     exitloop = FALSE;
  569.     while (!exitloop) {
  570.         if (l != ol) {
  571.             WNcolor(conf.norm);
  572.             if (ol >= 0)
  573.                 WNdisplay(2,ol+1,recs[ol]);
  574.             WNcolor(conf.high);
  575.             WNdisplay(2,l+1,recs[l]);
  576.             ol = l;
  577.         }
  578.         switch (KBgetch()) {
  579.             case ESCAPE :
  580.                 exitloop = TRUE;
  581.                 break;
  582.             case RETURN :
  583.                 exitloop = TRUE;
  584.                 retval = recn[l];
  585.                 break;
  586.             case CURUP :
  587.                 l = (l == 0 ? n-1 : l-1);
  588.                 break;
  589.             case CURDN :
  590.                 l = (l == n-1 ? 0 : l+1);
  591.                 break;
  592.         }
  593.     }
  594.  
  595.     WNcolor(conf.norm);
  596.     WNclose();
  597.     return(retval);
  598. }
  599.  
  600. void
  601. message(s)
  602.     char    *s;
  603. {
  604.     va_list    ap;
  605.     char    t[81];
  606.  
  607.     WNopen(2,2,79,2,conf.norm,POPUP,NULL);
  608.     va_start(ap,s);
  609.     vsprintf(t,s,ap);
  610.     va_end(ap);
  611.     strcat(t," : ");
  612.     WNputs(t);
  613.     KBgetch();
  614.     WNclose();
  615. }
  616.  
  617. void
  618. popup(s)
  619.     char    *s;
  620. {
  621.     int        l;
  622.  
  623.     l = 39-(strlen(s)/2);
  624.     WNopen(l,4,l+strlen(s)+1,4,conf.high,POPUP,NULL);
  625.     WNprintf(" %s",s);
  626.     delay(SHOWTIME);
  627. }
  628.  
  629. int
  630. getans(s)
  631.     char    *s;
  632. {
  633.     uchar    ch;
  634.  
  635.     WNopen(2,2,79,2,conf.norm,POPUP,NULL);
  636.     WNputc(' ');
  637.     WNputs(s);
  638.     ch = toupper(KBgetch());
  639.     WNclose();
  640.  
  641.     return(ch == 'Y' ? TRUE : FALSE);
  642. }
  643.  
  644. void
  645. rbrief()
  646. {
  647.     int        tmprn;
  648.     rec_st    t;
  649.     int        l;
  650.  
  651.     tmprn = DBrecno();
  652.     PRseterr(prerr);
  653.     l = 0;
  654.     DBgo(DBtop());
  655.     while (DBrecno() != 0) {
  656.         if (l++ > 59) {
  657.             PRputs("\014");
  658.             l = 1;
  659.         }
  660.         if (l == 1)
  661.             header("Brief Listing");
  662.         DBread(&t);
  663.         PRprintf("%-20s %-20s %-36.36s\r\n",t.sn,t.fn,t.addr1);
  664.         DBskip(1);
  665.     }
  666.     DBgo(tmprn);
  667. }
  668.  
  669. void
  670. prerr(s)
  671.     char    *s;
  672. {
  673.     message(s);
  674.     DBgo(DBbot());
  675. }
  676.  
  677. void
  678. rfull()
  679. {
  680.     int        tmprn;
  681.     rec_st    t;
  682.     int        l;
  683.  
  684.     tmprn = DBrecno();
  685.     PRseterr(prerr);
  686.     l = 0;
  687.     DBgo(DBtop());
  688.     while (DBrecno() != 0) {
  689.         if (l++ > 9) {
  690.             PRputs("\014");
  691.             l = 1;
  692.         }
  693.         if (l == 1)
  694.             header("Full Listing");
  695.         DBread(&t);
  696.         PRprintf("%-20s %-20s %s\r\n%-60s %s\r\n",t.sn,t.fn,
  697.             (t.paid == 'Y' ? "Paid" : "Not Paid"),t.addr1,t.phon);
  698.         PRputs(pline);
  699.         DBskip(1);
  700.     }
  701.     DBgo(tmprn);
  702. }
  703.  
  704. void
  705. header(s)
  706.     char    *s;
  707. {
  708.     PRprintf("\016%6sLibrary Demo System (v%s)\r\n","",version);
  709.     PRprintf("%*s%s\r\n",40-(strlen(s)/2),"",s);
  710.     PRputs(pline);
  711. }
  712.  
  713. void
  714. rpaid()
  715. {
  716.     int        tmprn;
  717.     rec_st    t;
  718.     int        l;
  719.  
  720.     tmprn = DBrecno();
  721.     PRseterr(prerr);
  722.     l = 0;
  723.     DBgo(DBtop());
  724.     while (DBrecno() != 0) {
  725.         DBread(&t);
  726.         if (t.paid != 'Y') {
  727.             if (l++ > 59) {
  728.                 PRputs("\014");
  729.                 l = 1;
  730.             }
  731.             if (l == 1)
  732.                 header("Unpaid Report");
  733.             PRprintf("%-20s %-20s %s\r\n",t.sn,t.fn,t.addr1);
  734.             DBskip(1);
  735.         }
  736.     }
  737.     DBgo(tmprn);
  738. }
  739.